/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.disorder;

import java.io.IOException;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import phoside.Protein;
import phoside.Proteins;
import phoside.io.fasta.parser.HeaderRule;

import phoside.util.StaticFinalValues;
/**
 *
 * @author gjj
 */
public class DisorderUtil {

    /**
     *
     * @param phosphoData
     * @param disorderFasta
     * @param headerParserRule
     */
    public static void integrateDisorder(final Proteins proteins,
            final String disorderFasta, final HeaderRule headerRule)
            throws IOException {
        if (proteins==null || disorderFasta==null) {
            throw new NullPointerException();
        }

        final DisorderInfoBatchRetriever disorderRetriever
                = new DisorderInfoBatchRetrieverFromFasta(disorderFasta, headerRule);

        final Map<String,List<Double>> mapAccDisorder = disorderRetriever.retrieve();

        integrateDisorder(proteins, mapAccDisorder);
    }

    /**
     * 
     * @param phosphoData
     * @param mapAccDisorder
     */
    public static void integrateDisorder(final Proteins proteins,
                                    final Map<String,List<Double>> mapAccDisorder) {
        if (proteins==null || mapAccDisorder==null) {
            throw new NullPointerException();
        }

        Iterator<Protein> it = proteins.proteinIterator();
        while (it.hasNext()) {
            Protein protein = it.next();
            List<Double> dis = mapAccDisorder.get(protein.getAccession());
            if (dis==null) {
                System.err.println("Disorder information is not available for "
                        +protein.getAccession());
                continue;
            }

            protein.putInfo(StaticFinalValues.DISORDER, dis);

        }
    }

    public static Map<String,List<Double>> predictDisorder(
                final Proteins proteins,
                final DisorderPredictor disorderPredictor,
                final boolean skipExist) {
        Map<String,List<Double>> result = new LinkedHashMap();
        Iterator<Protein> it = proteins.proteinIterator();
        while (it.hasNext()) {
            Protein protein = it.next();
            String acc = protein.getAccession();
            Object obj = protein.getInfo(StaticFinalValues.DISORDER);
            if (obj!=null && skipExist) {
                result.put(acc, (List)obj);
            } else {
                String seq = protein.getSequence();
                List<Double> dis = null;
                try {
                    dis = disorderPredictor.predict(seq);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (dis!=null) {
                    result.put(acc, dis);
                    //System.out.println(acc);
                } else {
                    System.err.println("Failed to predict disorder for "+acc);
                }
            }
        }

        return result;
    }

    public static void integrateDisorder(
                final Proteins proteins,
                final DisorderPredictor disorderPredictor,
                final boolean skipExist) {
        Map<String,List<Double>> dis = predictDisorder(proteins, 
                disorderPredictor, skipExist);
        integrateDisorder(proteins, dis);
    }
}
